﻿using System.Linq.Expressions;

namespace FreeSql;


public class RepositoryBase<TEntity, TKey> : BaseRepository<TEntity, TKey>,
    IRepositoryBase<TEntity, TKey> where TEntity : class
{

    public RepositoryBase(IFreeSql fsql, UnitOfWorkManager uowManger) : base(uowManger?.Orm ?? fsql)
    {
        uowManger?.Binding(this);
    }

    public virtual Task<TDto> GetAsync<TDto>(TKey id)
    {
        return Select.WhereDynamic(id).ToOneAsync<TDto>();
    }

    public virtual Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> exp)
    {
        return Select.Where(exp).ToOneAsync();
    }

    public virtual Task<TDto> GetAsync<TDto>(Expression<Func<TEntity, bool>> exp)
    {
        return Select.Where(exp).ToOneAsync<TDto>();
    }

}

public class RepositoryBase<TEntity> : RepositoryBase<TEntity, long>, IRepositoryBase<TEntity> where TEntity : class
{
    public RepositoryBase(IFreeSql fsql, UnitOfWorkManager uowManger) : base(fsql, uowManger)
    {
        uowManger?.Binding(this);
    }

}

public class RepositoryDefault<TEntity, TKey> : RepositoryBase<TEntity, TKey>, IRepositoryDefault<TEntity, TKey> where TEntity : class
{
    private readonly IAuthUser _authUser;

    public RepositoryDefault(IFreeSql fsql, UnitOfWorkManager uowManger, IAuthUser authUser) : base(fsql, uowManger)
    {
        uowManger?.Binding(this);
        _authUser = authUser;

    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<bool> SoftDeleteAsync(TKey id)
    {
        var count = await UpdateDiy
             .SetDto(new { IsDeleted = true, UpdatedBy = _authUser.Id, UpdatedByName = _authUser.UserName })
             .WhereDynamic(id)
             .ExecuteAffrowsAsync();
        return count > 0;
    }
    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="predicate"></param>
    /// <returns></returns>
    public async Task<bool> SoftDeleteAsync(Expression<Func<TEntity, bool>> predicate)
    {
        var count = await UpdateDiy
         .SetDto(new { IsDeleted = true, UpdatedBy = _authUser.Id, UpdatedByName = _authUser.UserName })
         .Where(predicate)
         .ExecuteAffrowsAsync();
        return count > 0;
    }


    public async Task<bool> SoftDeleteAsync(TKey[] ids)
    {
        var count = await UpdateDiy
             .SetDto(new { IsDeleted = true, UpdatedBy = _authUser.Id, UpdatedByName = _authUser.UserName })
             .WhereDynamic(ids)
             .ExecuteAffrowsAsync();
        return count > 0;
    }




    #region 恢复记录
    /// <summary>
    /// 恢复
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    public async Task<bool> RecoveryAsync(TKey id)
    {
        var count = await UpdateDiy
            .SetDto(new { IsDeleted = false, UpdatedBy = _authUser.Id, UpdatedByName = _authUser.UserName })
            .WhereDynamic(id).DisableGlobalFilter(nameof(IBaseSoftDelete))
            .ExecuteAffrowsAsync();
        return count > 0;

    }
    /// <summary>
    /// 恢复
    /// </summary>
    /// <param name="predicate"></param>
    /// <returns></returns>
    public async Task<bool> RecoveryAsync(Expression<Func<TEntity, bool>> predicate)
    {

        var count = await UpdateDiy
         .SetDto(new { IsDeleted = false, UpdatedBy = _authUser.Id, UpdatedByName = _authUser.UserName })
         .Where(predicate).DisableGlobalFilter(nameof(IBaseSoftDelete))
         .ExecuteAffrowsAsync();
        return count > 0;

    }
    /// <summary>
    /// 恢复
    /// </summary>
    /// <param name="ids"></param>
    /// <returns></returns>
    public async Task<bool> RecoveryAsync(TKey[] ids)
    {

        var count = await UpdateDiy
       .SetDto(new { IsDeleted = false, UpdatedBy = _authUser.Id, UpdatedByName = _authUser.UserName })
       .WhereDynamic(ids).DisableGlobalFilter(nameof(IBaseSoftDelete))
       .ExecuteAffrowsAsync();
        return count > 0;


    }
    #endregion
}



/// <summary>
/// 
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class RepositoryDefault<TEntity> : RepositoryDefault<TEntity, long>, IRepositoryDefault<TEntity> where TEntity : class
{

    public RepositoryDefault(IFreeSql fsql, UnitOfWorkManager uowManger, IAuthUser authUser) : base(fsql, uowManger, authUser)
    {
        uowManger?.Binding(this);
    }

}
